/**
 * 增强的数据验证服务
 * 提供统一的输入验证、数据清理和业务规则验证
 */

class ValidationService {
  constructor() {
    this.validationRules = new Map();
    this.customValidators = new Map();
    this.setupDefaultRules();
  }

  /**
   * 设置默认验证规则
   */
  setupDefaultRules() {
    // PPH记录验证规则
    this.addValidationRule('pph_record', {
      record_date: {
        required: true,
        type: 'date',
        format: 'YYYY-MM-DD'
      },
      line_name: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 50
      },
      order_number: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 100
      },
      start_time: {
        required: true,
        type: 'time',
        format: 'HH:MM'
      },
      end_time: {
        required: true,
        type: 'time',
        format: 'HH:MM'
      },
      quantity: {
        required: true,
        type: 'number',
        min: 0,
        max: 999999
      },
      total_people: {
        required: true,
        type: 'number',
        min: 1,
        max: 100
      },
      material_code: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 50
      },
      product_name: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 200
      },
      // 主打产品字段（统一使用正向逻辑）
      is_main_product: {
        required: false,
        type: 'boolean'
      },
      // 生产类型字段
      whole_machine_production: {
        required: false,
        type: 'boolean'
      }
    });

    // PPH目标值验证规则
    this.addValidationRule('pph_target', {
      material_code: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 50
      },
      product_name: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 200
      },
      record_date: {
        required: true,
        type: 'date',
        format: 'YYYY-MM-DD'
      },
      takt_time: {
        required: false,
        type: 'number',
        min: 0.1,
        max: 3600
      },
      motor_takt_time: {
        required: false,
        type: 'number',
        min: 0.1,
        max: 3600
      },
      standard_staff: {
        required: true,
        type: 'number',
        min: 1,
        max: 100
      },
      line_name: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 50
      },
      whole_machine_target: {
        required: false,
        type: 'number',
        min: 0,
        max: 1000
      },
      motor_target: {
        required: false,
        type: 'number',
        min: 0,
        max: 1000
      }
    });

    // PPH预估值验证规则
    this.addValidationRule('pph_estimate', {
      material_code: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 50
      },
      product_name: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 200
      },
      line_name: {
        required: true,
        type: 'string',
        minLength: 1,
        maxLength: 50
      },
      estimate_pph: {
        required: true,
        type: 'number',
        min: 0,
        max: 1000
      }
    });
  }

  /**
   * 添加验证规则
   */
  addValidationRule(entityType, rules) {
    this.validationRules.set(entityType, rules);
  }

  /**
   * 添加自定义验证器
   */
  addCustomValidator(name, validator) {
    this.customValidators.set(name, validator);
  }

  /**
   * 验证数据
   */
  validate(entityType, data) {
    const rules = this.validationRules.get(entityType);
    if (!rules) {
      throw new Error(`未找到实体类型 ${entityType} 的验证规则`);
    }

    const errors = [];
    const warnings = [];
    const cleanedData = {};

    // 验证每个字段
    for (const [fieldName, rule] of Object.entries(rules)) {
      const value = data[fieldName];
      const fieldErrors = this.validateField(fieldName, value, rule);
      
      if (fieldErrors.length > 0) {
        errors.push(...fieldErrors);
      } else {
        // 清理和转换数据
        cleanedData[fieldName] = this.cleanValue(value, rule);
      }
    }

    // 业务规则验证
    const businessValidation = this.validateBusinessRules(entityType, cleanedData);
    errors.push(...businessValidation.errors);
    warnings.push(...businessValidation.warnings);

    return {
      isValid: errors.length === 0,
      errors,
      warnings,
      cleanedData
    };
  }

  /**
   * 验证单个字段
   */
  validateField(fieldName, value, rule) {
    const errors = [];

    // 必填验证
    if (rule.required && (value === undefined || value === null || value === '')) {
      errors.push(`字段 ${fieldName} 是必填的`);
      return errors;
    }

    // 如果不是必填且值为空，跳过其他验证
    if (!rule.required && (value === undefined || value === null || value === '')) {
      return errors;
    }

    // 类型验证
    if (rule.type) {
      const typeError = this.validateType(fieldName, value, rule.type);
      if (typeError) {
        errors.push(typeError);
        return errors; // 类型错误时不继续验证
      }
    }

    // 长度验证
    if (rule.minLength !== undefined && value.length < rule.minLength) {
      errors.push(`字段 ${fieldName} 长度不能少于 ${rule.minLength} 个字符`);
    }
    if (rule.maxLength !== undefined && value.length > rule.maxLength) {
      errors.push(`字段 ${fieldName} 长度不能超过 ${rule.maxLength} 个字符`);
    }

    // 数值范围验证
    if (rule.min !== undefined && Number(value) < rule.min) {
      errors.push(`字段 ${fieldName} 不能小于 ${rule.min}`);
    }
    if (rule.max !== undefined && Number(value) > rule.max) {
      errors.push(`字段 ${fieldName} 不能大于 ${rule.max}`);
    }

    // 格式验证
    if (rule.format) {
      const formatError = this.validateFormat(fieldName, value, rule.format);
      if (formatError) {
        errors.push(formatError);
      }
    }

    // 自定义验证器
    if (rule.customValidator) {
      const validator = this.customValidators.get(rule.customValidator);
      if (validator) {
        const customError = validator(fieldName, value);
        if (customError) {
          errors.push(customError);
        }
      }
    }

    return errors;
  }

  /**
   * 类型验证
   */
  validateType(fieldName, value, expectedType) {
    switch (expectedType) {
      case 'string':
        if (typeof value !== 'string') {
          return `字段 ${fieldName} 必须是字符串类型`;
        }
        break;
      case 'number':
        if (isNaN(Number(value))) {
          return `字段 ${fieldName} 必须是数字类型`;
        }
        break;
      case 'date':
        if (!this.isValidDate(value)) {
          return `字段 ${fieldName} 必须是有效的日期格式`;
        }
        break;
      case 'time':
        if (!this.isValidTime(value)) {
          return `字段 ${fieldName} 必须是有效的时间格式`;
        }
        break;
      case 'boolean':
        // 更宽松的布尔值验证，支持多种格式
        if (value !== true && value !== false &&
            value !== 'true' && value !== 'false' &&
            value !== 1 && value !== 0 &&
            value !== '1' && value !== '0') {
          return `字段 ${fieldName} 必须是布尔类型`;
        }
        break;
    }
    return null;
  }

  /**
   * 格式验证
   */
  validateFormat(fieldName, value, format) {
    switch (format) {
      case 'YYYY-MM-DD':
        if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
          return `字段 ${fieldName} 必须是 YYYY-MM-DD 格式`;
        }
        break;
      case 'HH:MM':
        if (!/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/.test(value)) {
          return `字段 ${fieldName} 必须是 HH:MM 格式`;
        }
        break;
    }
    return null;
  }

  /**
   * 业务规则验证
   */
  validateBusinessRules(entityType, data) {
    const errors = [];
    const warnings = [];

    switch (entityType) {
      case 'pph_record':
        // 验证时间逻辑
        if (data.start_time && data.end_time) {
          const startMinutes = this.timeToMinutes(data.start_time);
          const endMinutes = this.timeToMinutes(data.end_time);
          
          if (startMinutes >= endMinutes) {
            errors.push('结束时间必须晚于开始时间');
          }
        }

        // 验证数量合理性
        if (data.quantity && data.total_people) {
          const pphEstimate = data.quantity / data.total_people;
          if (pphEstimate > 100) {
            warnings.push('计算的PPH值异常高，请检查数据');
          }
        }
        break;

      case 'pph_target':
        // 验证目标值合理性
        if (data.whole_machine_target && data.motor_target) {
          if (data.motor_target > data.whole_machine_target) {
            warnings.push('电机目标值通常不应高于整机目标值');
          }
        }
        break;
    }

    return { errors, warnings };
  }

  /**
   * 清理数据值
   */
  cleanValue(value, rule) {
    if (value === undefined || value === null) {
      return value;
    }

    switch (rule.type) {
      case 'string':
        return String(value).trim();
      case 'number':
        return Number(value);
      case 'boolean':
        return value === true || value === 'true';
      default:
        return value;
    }
  }

  /**
   * 验证日期格式
   */
  isValidDate(dateString) {
    const date = new Date(dateString);
    return date instanceof Date && !isNaN(date);
  }

  /**
   * 验证时间格式
   */
  isValidTime(timeString) {
    return /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/.test(timeString);
  }

  /**
   * 时间转换为分钟
   */
  timeToMinutes(timeString) {
    const [hours, minutes] = timeString.split(':').map(Number);
    return hours * 60 + minutes;
  }
}

module.exports = ValidationService;
